package cn.juque.jdfsystem.helper;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.juque.common.base.BaseResponseVO;
import cn.juque.common.constants.StringConstants;
import cn.juque.common.fastjson.abstracts.AbstractTypeReference;
import cn.juque.common.utils.HttpClientUtil;
import cn.juque.common.utils.dto.PostDTO;
import cn.juque.jdfsystem.cache.RegisterInfoCache;
import cn.juque.jdfsystem.contants.UrlConstants;
import cn.juque.jdfsystem.entity.FileInfo;
import cn.juque.lucenecandy.cache.IpCache;
import cn.juque.lucenecandy.core.utils.SignatureUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author juque
 * @version 1.0.0
 * <ul>
 *     <li>FileInfoHelper</li>
 * </ul>
 * @date 2023-12-13 18:46:37
 **/
@Component("fileInfoHelper")
public class FileInfoHelper {

    @Resource
    private RegisterInfoCache registerInfoCache;

    @Resource
    private IpCache ipCache;

    public File getFile(FileInfo fileInfo) {
        String fileName = fileInfo.getId() + StringConstants.POINT + fileInfo.getFileExt();
        return FileUtil.file(fileInfo.getServerPath(), fileName);
    }

    /**
     * 并行检查文件所在的机器
     *
     * @param ipList ip列表
     * @param fileId 文件ID
     * @return list
     */
    public List<String> parallelCheckFile(List<String> ipList, String fileId) {
        List<String> successIpList = ipList.parallelStream().map(ip -> {
            String url = this.ipCache.buildUrl(ip, UrlConstants.MESSAGE_CHECK_FILE);
            url = CharSequenceUtil.format(url, fileId);
            PostDTO postDTO = new PostDTO(SignatureUtil.buildUrl(url), null, null);
            BaseResponseVO<Boolean> resp = HttpClientUtil.post(postDTO, new AbstractTypeReference<BaseResponseVO<Boolean>>() {
            });

            return Boolean.TRUE.equals(resp.getData()) ? ip : CharSequenceUtil.EMPTY;
        }).collect(Collectors.toList());
        return successIpList.stream().filter(Objects::nonNull).collect(Collectors.toList());
    }

    public String parallelFindFile(String fileId) {
        Map<String, Set<String>> validIpMap = this.registerInfoCache.getValidIpMap(null, false);
        List<String> ipList = new ArrayList<>(validIpMap.size());
        validIpMap.forEach((k, v) -> ipList.add(CollUtil.getFirst(v)));
        List<List<String>> list = ipList.parallelStream().map(ip -> {
            String url = this.ipCache.buildUrl(ip, UrlConstants.MESSAGE_FIND_FILE);
            url = CharSequenceUtil.format(url, fileId);
            PostDTO postDTO = new PostDTO(SignatureUtil.buildUrl(url), null, null);
            BaseResponseVO<List<String>> resp = HttpClientUtil
                    .post(postDTO, new AbstractTypeReference<BaseResponseVO<List<String>>>() {
                    });
            return resp.getData();
        }).collect(Collectors.toList());
        for (List<String> subList : list) {
            if (CollUtil.isNotEmpty(subList)) {
                return subList.get(0);
            }
        }
        return CharSequenceUtil.EMPTY;
    }

}
